/**
 * @file util/field
 * @author  fanxl
 */
import type {UnionSpecItem} from '../interface/spec';
import type {BasicField} from '../interface/field';
import {Validator} from '../validator/validator';
import {isEmpty, isString} from 'lodash-es';

function handleNewExpression(data: any) {
    if (data && !isEmpty(data)) {
        data = data.map((v: any) => {
            return isString(v) ? JSON.parse(v) : v;
        });
    }
    return data;
}

export function getBasicField(spec: UnionSpecItem, path: string, showIndex: number) {
    const {
        name,
        idx,
        displayName,
        display,
        readOnly,
        disabled,
        nameTip,
        tip,
        descriptionTip,
        rules,
        extraAttr,
        ':hidden': hiddenOld,
        ':remove': removeOld
    } = spec;
    const hiddenExpression = handleNewExpression(spec.hiddenExpression);
    const removeExpression = handleNewExpression(spec.removeExpression);

    if (hiddenOld && hiddenExpression) {
        throw new Error(
            `[SPEC数据异常]: 新旧版表达式不可同时存在, :hidden: ${hiddenOld}, hiddenExpression: ${JSON.stringify(
                hiddenExpression
            )}`
        );
    }
    if (removeOld && removeExpression) {
        throw new Error(
            `[SPEC数据异常]: 新旧版表达式不可同时存在, :remove: ${removeOld}, removeExpression: ${JSON.stringify(
                removeExpression
            )}`
        );
    }
    let validators;
    let required = false;
    if (rules) {
        validators = new Validator(rules).genValidators();
        required = !!rules.required;
    }
    let extensions;
    if (extraAttr?.extensions) {
        extensions = extraAttr.extensions;
    }
    let reactions;
    if (extraAttr?.reactions) {
        reactions = extraAttr.reactions;
    }
    let slots;
    if (extraAttr?.slots) {
        slots = extraAttr.slots;
    }
    // 新旧版表达式合并到一个字段
    const hidden = hiddenOld || hiddenExpression;
    const remove = removeOld || removeExpression;
    return {
        name,
        path: path ? [path, spec.name].join('.') : spec.name,
        showIndex,
        idx,
        displayName: displayName || '',
        display,
        readOnly,
        disabled,
        required,
        nameTip,
        tip,
        descriptionTip,
        extensions,
        reactions,
        validating: false,
        modified: false,
        validators,
        hidden,
        remove,
        slots
    } as BasicField;
}
